import { Component, ViewChild, ElementRef, AfterViewInit, OnInit, Output, EventEmitter, Input, OnDestroy } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { FormControl } from '@angular/forms';
import { MatAutocomplete, MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { Observable, BehaviorSubject } from 'rxjs';
import { map, startWith } from 'rxjs/operators';

export interface ChipItem {
  id: number | string;
  name: string;
  // ...any other properties
}

@Component({
  selector: 'app-horizontal-item-list',
  templateUrl: './horizontal-item-list.component.html',
  styleUrls: ['./horizontal-item-list.component.scss']
})
export class HorizontalItemListComponent implements AfterViewInit, OnInit, OnDestroy {
  @ViewChild('scrollContainer') scrollContainer!: ElementRef<HTMLDivElement>;
  @ViewChild('chipInput') chipInput!: ElementRef<HTMLInputElement>;
  @ViewChild('auto') matAutocomplete!: MatAutocomplete;
  @ViewChild('autoTrigger', { read: MatAutocompleteTrigger }) autocompleteTrigger!: MatAutocompleteTrigger;
  @Output() chipsChange = new EventEmitter<ChipItem[]>();
  @Input() allChips: ChipItem[] = [];
  @Input() label: string = '';
  @Input() placeholder: string = '';
  @Input() initialChips: ChipItem[] = [];

  private _chips = new BehaviorSubject<ChipItem[]>([]);
  chips$: Observable<ChipItem[]> = this._chips.asObservable();
  get chips(): ChipItem[] {
    return this._chips.getValue();
  }
  set chips(value: ChipItem[]) {
    this._chips.next(value);
    this.chipsChange.emit(value);
  }

  removable = true;
  chipCtrl = new FormControl('');
  filteredChips!: Observable<ChipItem[]>;

  // Add this property to track selected checkboxes
  selectedOptions: ChipItem[] = [];

  showScrollButtons = false;

  // Add this property to track ALL Options toggle
  allOptionsSelected = false;

  constructor(private snackBar: MatSnackBar) {}

  displayFn = (chip: ChipItem): string => {
    return chip ? chip.name : '';
  }

  ngOnInit() {
    this._chips.next(this.initialChips || []);
    this.filteredChips = this.chipCtrl.valueChanges.pipe(
      startWith(''),
      map(value => {
        if (typeof value === 'string') {
          const filter = value.toLowerCase();
          const filtered = this.allChips.filter(chip =>
            chip.name.toLowerCase().includes(filter) &&
            !this.chips.some(selectedChip => selectedChip.id === chip.id)
          );
          this.allOptionsSelected = filtered.length === 0 && this.chips.length === this.allChips.length && this.allChips.length > 0;
          if (this.allOptionsSelected) {
            this.updateScrollButtons();
          }
          return filtered;
        }
        return [];
      })
    );
    // Update scroll buttons when chips change
    this.chips$.subscribe(() => this.updateScrollButtons());
  }

  ngAfterViewInit(): void {
    this.updateScrollButtons();
    window.addEventListener('resize', this.updateScrollButtonsBound);
  }

  ngOnDestroy(): void {
    window.removeEventListener('resize', this.updateScrollButtonsBound);
  }

  // Use a bound version for add/remove event listeners
  private updateScrollButtonsBound = this.updateScrollButtons.bind(this);

  updateScrollButtons() {
    if (this.scrollContainer && this.scrollContainer.nativeElement) {
      const el = this.scrollContainer.nativeElement;
      this.showScrollButtons = el.scrollWidth > el.clientWidth;
    }
  }

  removeChip(index: number): void {
    if (index >= 0) {
      const currentChips = [...this.chips];
      currentChips.splice(index, 1);
      this.chips = currentChips;
      this.chipCtrl.setValue('');
    }
  }

  add(event: { input: HTMLInputElement, value: string }): void {
    const value = (event.value || '').trim();
    if (value) {
      const found = this.allChips.find(chip => chip.name.toLowerCase() === value.toLowerCase());
      if (found && !this.chips.some(c => c.id === found.id)) {
        this.chips = [...this.chips, found];
        if (event.input) {
          event.input.value = '';
        }
        this.chipCtrl.setValue('');
      }
    }
  }

  selectedChip(event: MatAutocompleteSelectedEvent): void {
    const selectedChipItem: ChipItem = event.option.value;
    if (selectedChipItem && !this.chips.some(c => c.id === selectedChipItem.id)) {
      this.chips = [...this.chips, selectedChipItem];
      this.chipInput.nativeElement.value = '';
      this.chipCtrl.setValue('');
    }
  }

  onChipClick(chip: ChipItem): void {
  }

  scrollLeft(): void {
    this.scrollContainer.nativeElement.scrollLeft -= 150;
  }

  scrollRight(): void {
    this.scrollContainer.nativeElement.scrollLeft += 150;
  }

  // Toggle selection for a chip
  public toggleOptionSelection(chip: ChipItem): void {
    const idx = this.selectedOptions.findIndex(c => c.id === chip.id);
    if (idx === -1) {
      this.selectedOptions.push(chip);
    } else {
      this.selectedOptions.splice(idx, 1);
    }
  }

  // Check if a chip is selected
  public isOptionSelected(chip: ChipItem): boolean {
    return this.selectedOptions.some(c => c.id === chip.id);
  }

  // Confirm selection and add selected chips
  public confirmOptionSelection(): void {
    // Only add chips that are not already present
    const newChips = this.selectedOptions.filter(
      chip => !this.chips.some(c => c.id === chip.id)
    );
    this.chips = [...this.chips, ...newChips];
    this.selectedOptions = [];
    this.chipCtrl.setValue('');
    if (this.autocompleteTrigger) {
      this.autocompleteTrigger.closePanel();
    }
    this.updateScrollButtons();
  }

  removeChipById(id: number | string): void {
    const currentChips = this.chips.filter(chip => chip.id !== id);
    this.chips = currentChips;
    this.chipCtrl.setValue('');
  }

  onAllOptionsToggle(event: any) {
    if (event.checked) {
      this.chips = [...this.allChips];
      this.allOptionsSelected = true;
      this.updateScrollButtons();
    } else {
      this.chips = [];
      this.allOptionsSelected = false;
      this.updateScrollButtons();
      this.chipCtrl.setValue('');
    }
  }
}